#include "bootload.h"
#include "stdio.h"
#include "main.h"
typedef  void (*pFuncType)(void);

uint8_t  OverTimeCount = 100;

void BootLoadJumpToApplication(uint32_t u32AppAddr) {
    pFuncType JumpToApplication;

    if(((*(__IO uint32_t*)u32AppAddr) & 0x2FFE0000) == 0x20000000) {
        JumpToApplication = (pFuncType) * ((__IO uint32_t *)(u32AppAddr + 4));
        __set_MSP(*(__IO uint32_t*)u32AppAddr);
        JumpToApplication();
    } else {
        HAL_Delay(500);

        while(--OverTimeCount) {
            HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
            HAL_Delay(50);
        }

        REBOOT;
    }
}

#if 0

void BootLoadMain(void) {
    uint32_t ErrorCode, FirmwareSize, FirwareVersion, UpdataFlag;
    FLASH_EraseInitTypeDef FlashErase;

    FirmwareSize = (*(__IO uint32_t *)FIRMWARE_SIZE_ADDR);
    UpdataFlag = *(__IO uint32_t *)FIRMWARE_DEV_ADDR;
    FirwareVersion = *(__IO uint32_t *)FIRMWARE_VERSION;

    if(0U == FirmwareSize || FirmwareSize > FIRMWARE_SIZE_MAX) {
        UpdataFlag = 0;
    }

    DEBUG("Firmware Updata Flag: 0x%08X  FirmwareSize: 0x%08X\n", UpdataFlag, FirmwareSize);

    if(UpdataFlag == 0) {
        DEBUG("App Jumping...\n");
        __disable_irq();
        HAL_Delay(300);                               //����ʱ�ǳ���Ҫ
        BootLoadJumpToApplication(APPLICATION_ADDR);

    } else { //��Ҫ��Flash�г��򻺳������ݸ��Ƶ�Ӧ����
        HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);

        FlashErase.TypeErase   = FLASH_TYPEERASE_PAGES;
        FlashErase.PageAddress = APPLICATION_ADDR;
        FlashErase.NbPages     = FirmwareSize / PAGE_SIZE + 1;

        HAL_FLASH_Unlock();

        if(HAL_OK != HAL_FLASHEx_Erase(&FlashErase, &ErrorCode)) {
            DEBUG("Flash Erase Failed! (Code) Error Address: %d\r\n", ErrorCode);
        } else {
            DEBUG("Flash Erase Successful (%08X~%08X)\r\n", APPLICATION_ADDR, APPLICATION_ADDR + FirmwareSize);

            uint32_t SrcAddr, DesAddr;

            SrcAddr = FIRMWARE_START_ADDR;
            DesAddr = APPLICATION_ADDR;

            for(uint16_t i = 0; i < FirmwareSize; i += 4) {
                HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, DesAddr + i, *(__IO uint32_t *)(SrcAddr + i));
            }

            HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FIRMWARE_DEV_ADDR, 0);
            DEBUG("Firmware Updata set 0: %08X\n", *(__IO uint32_t *)FIRMWARE_DEV_ADDR);
            HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FIRMWARE_VERSION, ++FirwareVersion);
            DEBUG("Firmware Version: %08X\n", *(__IO uint32_t *)FIRMWARE_VERSION);
        }

        HAL_FLASH_Lock();

        DEBUG("Reboot....\n");
        HAL_Delay(100);
        REBOOT;
    }
}

#endif



void BootLoadJumpToApp(uint32_t u32AppAddr) {
    __disable_irq();
    BootLoadJumpToApplication(u32AppAddr);
	while(1);
}


void BootLoadToFlash(uint8_t *data,uint32_t len,uint32_t Address) 
{
    FLASH_EraseInitTypeDef FlashErase;
	
		uint32_t ErrorCode = 0;
    HAL_FLASH_Unlock();

    FlashErase.TypeErase   = FLASH_TYPEERASE_PAGES;
    FlashErase.PageAddress = Address;
    FlashErase.NbPages     = (len / PAGE_SIZE )+ 1;
		DEBUG("Firmware Offset: %08X\n", Address);
		DEBUG("Firmware Length: %05d\n", len);
	
    if(HAL_OK != HAL_FLASHEx_Erase(&FlashErase, &ErrorCode))
		{
        DEBUG("\r\nFlash Erase Failed! (Code) Error Address: %d", ErrorCode);
    }
		else
		{
				DEBUG("\r\nFlash Erase Success!");
        for(uint16_t i = 0; i < len; i += 4)
				{
					HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address + i, *(__IO uint64_t*)(data + i));
        }
				DEBUG("\r\nFlash Program Success!");
        //HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FIRMWARE_DEV_ADDR, 0);
        //DEBUG("Firmware Updata set 0: %08X\n", *(__IO uint32_t *)FIRMWARE_DEV_ADDR);
        //HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FIRMWARE_VERSION, ++FirwareVersion);
        //DEBUG("Firmware Version: %08X\n", *(__IO uint32_t *)FIRMWARE_VERSION);
    }
    HAL_FLASH_Lock();
    return ;
}




